package com.sevntu.apvs.lab1;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class SourceGraphData {
	private int arcGivenCount = -1;
	private int nodeCurrentCount = -1;
	private int arcCurrentCount = -1;
	private static final int NUM_IN_LEVEL_CODE = 2;
	private byte[][] incidenceMatrix = null;
	private byte[] modelRAM = null;

	public SourceGraphData(final int numGraphArcN, final int currentNumOfNodes,
			final int currentNumOfArcs, byte incidenceMatr[][]) {
		arcGivenCount = numGraphArcN;
		nodeCurrentCount = currentNumOfNodes;
		arcCurrentCount = currentNumOfArcs;
		incidenceMatrix = incidenceMatr;
	}

	public SourceGraphData(final String graphDataInputFileName) {
		readGraphDataFromFile(graphDataInputFileName);
	}

	public int getArcGivenCount() {
		return arcGivenCount;
	}

	public int getNodeCurrentCount() {
		return nodeCurrentCount;
	}

	public int getArcCurrentCount() {
		return arcCurrentCount;
	}

	public byte[] getModelRAM() {
		int fillToFullByte = 8 - ((nodeCurrentCount % 8) * 2);
		if (fillToFullByte == 8)
			fillToFullByte = 0;
		modelRAM = new byte[NUM_IN_LEVEL_CODE * arcCurrentCount
				* nodeCurrentCount + (fillToFullByte * arcCurrentCount)];

		boolean isOne = false, isMinusOne = false;

		for (int indexi = 0, indexInRAM = 0; indexi < arcCurrentCount; indexi++) {
			for (int indexj = 0; indexj < nodeCurrentCount; indexj++, indexInRAM += 2) {

				switch (incidenceMatrix[indexi][indexj]) {
				case -1: {
					if (isMinusOne) {
						System.err.println("One arc has more then 2 nods!!");
						System.exit(0);
					}
					modelRAM[indexInRAM] = 1;
					modelRAM[indexInRAM + 1] = 0;
					isMinusOne = true;
					break;
				}
				case 0: {
					modelRAM[indexInRAM] = 0;
					modelRAM[indexInRAM + 1] = 0;
					break;
				}
				case 1: {
					if (isOne) {
						System.err.println("One arc has more then 2 nods!!");
						System.exit(0);
					}
					modelRAM[indexInRAM] = 0;
					modelRAM[indexInRAM + 1] = 1;
					isOne = true;
					break;
				}
				default: {
					System.err
							.println("There's an error in incidence matrix in the "
									+ (indexi + 1)
									+ " line, "
									+ (indexj + 1)
									+ " value!!");
					System.exit(0);
				}
				}
			}
			if (!isOne && !isMinusOne || isOne && !isMinusOne || !isOne && isMinusOne) {
				System.err.println("One arc has less then 2 nods!!");
				System.exit(0);
			}
			for (int indexj = 0; indexj < fillToFullByte; indexj++, indexInRAM++) {
				modelRAM[indexInRAM] = 0;
			}
			isOne = false;
			isMinusOne = false;
		}

		return modelRAM;
	}

	private void readGraphDataFromFile(final String graphDataInputFileName) {
		BufferedReader inputFileName = null;

		try {
			inputFileName = new BufferedReader(new FileReader(
					graphDataInputFileName));
			String strReadLine;
			String fileData[];
			int countFileLines = 0;

			while ((strReadLine = inputFileName.readLine()) != null) {
				strReadLine = strReadLine.trim();
				fileData = strReadLine.split("\\s+");

				for (int index = 0; index < fileData.length; index++) {
					switch (countFileLines) {
					case 0: {
						arcGivenCount = Byte.decode(fileData[0]);
						if (arcGivenCount < 1) {
							System.err.println("Wrong number of given arcs!!");
							System.exit(0);
						}
						break;
					}
					case 1: {
						nodeCurrentCount = Byte.decode(fileData[0]);
						if (nodeCurrentCount > 16 || nodeCurrentCount < 1) {
							System.err
									.println("Wrong number of current nods!!");
							System.exit(0);
						}
						break;
					}
					case 2: {
						arcCurrentCount = Byte.decode(fileData[0]);
						if (arcCurrentCount < 1) {
							System.err
									.println("Wrong number of current arcs!!");
							System.exit(0);
						}
						incidenceMatrix = new byte[arcCurrentCount][nodeCurrentCount];
						break;
					}
					default: {
						if (fileData.length != nodeCurrentCount
								|| (countFileLines - 2) > arcCurrentCount) {
							System.err
									.println("There's an error in incidence matrix in the "
											+ (countFileLines - 2) + " line!!");
							System.exit(0);
						}
						incidenceMatrix[countFileLines - 3][index] = Byte
								.decode(fileData[index]);
					}
					}
				}
				countFileLines++;
			}
			if (countFileLines - 3 < arcCurrentCount) {
				System.err.println("There's no data in incidence matrix in the "
						+ (countFileLines - 2) + " line!!");
				System.exit(0);
			}
		} catch (IOException e) {
			System.err.println("Error in opening file!!");
			System.exit(0);
		} catch (Exception e) {
			System.err.println("Wrong data!!");
			System.exit(0);
		} finally {
			try {
				inputFileName.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
